// This data is for a list of just 1 subdimension, but we would have N subdimensions to graph. (Needs N containers in the UI)

// There is also have a function that converts our pandas dataframe to this format.

// Each item in `graphs` represents the data for a single graph.
// Each graph has the following properties:
//   - title: Title of the graph
//   - y_axis_label: Title of the y-axis
//   - x_axis_label: Title of the x-axis
//   - sub_dimension: The sub-dimension of the graph.
//   - intervals: The confidence interval at a date in the form: [timestamp, low, high]
//   - values: The value at a date in the form: [timestamp, value]
//   - predicted_values: The predicted value at a date in the form: [timestamp, predicted_value]
let graphs = [
  {
    title: "overall KPI using prophet",
    y_axis_label: "Count of D num_purchases",
    x_axis_label: "Datetime",
    sub_dimension: "overall KPI",
    intervals: [
      [1308096000000.0, 954.69, 2020.7],
      [1308182400000.0, 1084.21, 2085.84],
      [1308268800000.0, 677.02, 1753.51],
      [1308355200000.0, -594.07, 463.11],
      [1308441600000.0, 464.28, 1501.97],
      [1308528000000.0, 884.53, 1876.43],
      [1308614400000.0, 1032.99, 2014.83],
      [1308700800000.0, 978.51, 1965.33],
      [1308787200000.0, 1050.41, 2115.82],
      [1308873600000.0, 681.72, 1702.59],
      [1308960000000.0, -571.91, 450.9],
      [1309046400000.0, 478.97, 1505.33],
      [1309132800000.0, 862.0, 1900.0],
      [1309219200000.0, 1023.83, 2101.78],
      [1309305600000.0, 947.94, 2028.65],
      [1309392000000.0, 1084.65, 2123.94],
      [1309478400000.0, 715.87, 1742.34],
      [1309564800000.0, -595.08, 431.56],
      [1309651200000.0, 494.44, 1548.0],
      [1309737600000.0, 916.7, 1932.85],
      [1309824000000.0, 1039.0, 2045.52],
      [1309910400000.0, 976.07, 2066.08],
      [1309996800000.0, 1114.61, 2134.73],
      [1310083200000.0, 673.26, 1740.75],
      [1310169600000.0, -509.12, 527.44],
      [1310256000000.0, 480.38, 1551.95],
      [1310342400000.0, 898.02, 1937.55],
      [1310428800000.0, 1061.25, 2093.57],
      [1310515200000.0, 1001.22, 2037.33],
      [1310601600000.0, 1094.28, 2178.23],
      [1310688000000.0, 684.03, 1783.26],
      [1310774400000.0, -546.27, 486.32],
      [1310860800000.0, 510.44, 1526.69],
      [1310947200000.0, 893.75, 2007.17],
      [1311033600000.0, 1077.37, 2097.96],
      [1311120000000.0, 994.71, 2040.03],
      [1311206400000.0, 1096.11, 2130.61],
      [1311292800000.0, 720.08, 1749.77],
      [1311379200000.0, -501.8, 537.18],
      [1311465600000.0, 527.73, 1537.0],
      [1311552000000.0, 964.22, 1950.84],
      [1311638400000.0, 1074.39, 2081.1],
      [1311724800000.0, 1032.67, 2057.56],
      [1311811200000.0, 1116.43, 2152.94],
      [1311897600000.0, 729.08, 1775.67],
      [1311984000000.0, -571.76, 542.09],
      [1312070400000.0, 512.69, 1575.9],
      [1312156800000.0, 920.72, 1977.82],
      [1312243200000.0, 1038.8, 2129.15],
      [1312329600000.0, 992.39, 2035.5],
      [1312416000000.0, 1129.59, 2145.77],
      [1312502400000.0, 723.8, 1782.44],
      [1312588800000.0, -493.87, 513.25],
      [1312675200000.0, 512.6, 1555.91],
      [1312761600000.0, 969.36, 1973.01],
      [1312848000000.0, 1087.87, 2121.13],
      [1312934400000.0, 1028.61, 2091.77],
      [1313020800000.0, 1130.25, 2148.44],
      [1313107200000.0, 774.14, 1783.76],
      [1313193600000.0, -473.26, 558.46],
      [1313280000000.0, 551.43, 1556.2],
      [1313366400000.0, 937.88, 2008.45],
      [1313452800000.0, 1107.59, 2146.63],
      [1313539200000.0, 1031.3, 2072.1],
      [1313625600000.0, 1157.18, 2231.09],
      [1313712000000.0, 764.44, 1789.03],
      [1313798400000.0, -509.48, 558.23],
      [1313884800000.0, 510.66, 1605.38],
      [1313971200000.0, 994.19, 2001.41],
      [1314057600000.0, 1130.75, 2129.26],
      [1314144000000.0, 1075.99, 2107.24],
      [1314230400000.0, 1152.07, 2210.61],
      [1314316800000.0, 765.24, 1783.62],
      [1314403200000.0, -502.69, 545.37],
      [1314489600000.0, 566.17, 1571.8],
      [1314576000000.0, 962.52, 1999.55],
      [1314662400000.0, 1108.51, 2147.24],
      [1314748800000.0, 1111.26, 2124.46],
      [1314835200000.0, 1168.51, 2215.89],
      [1314921600000.0, 747.68, 1797.2],
      [1315008000000.0, -470.79, 531.46],
      [1315094400000.0, 612.66, 1602.09],
      [1315180800000.0, 972.61, 2033.27],
      [1315267200000.0, 1147.95, 2156.86],
      [1315353600000.0, 1097.6, 2101.39],
      [1315440000000.0, 1142.6, 2236.15],
      [1315526400000.0, 795.85, 1847.18],
      [1315612800000.0, -489.27, 555.78],
      [1315699200000.0, 594.62, 1651.74],
      [1315785600000.0, 1018.47, 2068.9],
      [1315872000000.0, 1142.5, 2174.9],
      [1315958400000.0, 1108.96, 2099.18],
    ],
    values: [
      [1308096000000.0, 1683],
      [1308182400000.0, 1503],
      [1308268800000.0, 942],
      [1308355200000.0, 0],
      [1308441600000.0, 1157],
      [1308528000000.0, 1978],
      [1308614400000.0, 1453],
      [1308700800000.0, 1008],
      [1308787200000.0, 1948],
      [1308873600000.0, 1024],
      [1308960000000.0, 0],
      [1309046400000.0, 667],
      [1309132800000.0, 1156],
      [1309219200000.0, 999],
      [1309305600000.0, 1315],
      [1309392000000.0, 1609],
      [1309478400000.0, 978],
      [1309564800000.0, 0],
      [1309651200000.0, 598],
      [1309737600000.0, 2185],
      [1309824000000.0, 2175],
      [1309910400000.0, 1795],
      [1309996800000.0, 1896],
      [1310083200000.0, 1579],
      [1310169600000.0, 0],
      [1310256000000.0, 815],
      [1310342400000.0, 1490],
      [1310428800000.0, 1646],
      [1310515200000.0, 1610],
      [1310601600000.0, 1663],
      [1310688000000.0, 1118],
      [1310774400000.0, 0],
      [1310860800000.0, 1246],
      [1310947200000.0, 2167],
      [1311033600000.0, 1576],
      [1311120000000.0, 1993],
      [1311206400000.0, 1494],
      [1311292800000.0, 1281],
      [1311379200000.0, 0],
      [1311465600000.0, 1116],
      [1311552000000.0, 1935],
      [1311638400000.0, 1233],
      [1311724800000.0, 1228],
      [1311811200000.0, 1510],
      [1311897600000.0, 1119],
      [1311984000000.0, 0],
      [1312070400000.0, 1270],
      [1312156800000.0, 1189],
      [1312243200000.0, 1332],
      [1312329600000.0, 1521],
      [1312416000000.0, 1782],
      [1312502400000.0, 1442],
      [1312588800000.0, 0],
      [1312675200000.0, 529],
      [1312761600000.0, 1455],
      [1312848000000.0, 1087],
      [1312934400000.0, 1360],
      [1313020800000.0, 1935],
      [1313107200000.0, 1113],
      [1313193600000.0, 0],
      [1313280000000.0, 538],
      [1313366400000.0, 918],
      [1313452800000.0, 1022],
      [1313539200000.0, 1651],
      [1313625600000.0, 1487],
      [1313712000000.0, 811],
      [1313798400000.0, 0],
      [1313884800000.0, 1065],
      [1313971200000.0, 1267],
      [1314057600000.0, 1434],
      [1314144000000.0, 1820],
      [1314230400000.0, 1291],
      [1314316800000.0, 925],
      [1314403200000.0, 0],
      [1314489600000.0, 1196],
      [1314576000000.0, 0],
      [1314662400000.0, 3218],
      [1314748800000.0, 1176],
      [1314835200000.0, 1399],
      [1314921600000.0, 2333],
      [1315008000000.0, 0],
      [1315094400000.0, 1333],
      [1315180800000.0, 1569],
      [1315267200000.0, 1122],
      [1315353600000.0, 2080],
      [1315440000000.0, 1750],
      [1315526400000.0, 1558],
      [1315612800000.0, 0],
      [1315699200000.0, 2027],
      [1315785600000.0, 1638],
      [1315872000000.0, 2428],
      [1315958400000.0, 2533],
      // [1315958400000.0, 1333],
    ],
    predicted_values: [
      [1308096000000.0, 1474.19],
      [1308182400000.0, 1574.33],
      [1308268800000.0, 1186.34],
      [1308355200000.0, -61.53],
      [1308441600000.0, 981.28],
      [1308528000000.0, 1395.88],
      [1308614400000.0, 1532.64],
      [1308700800000.0, 1484.46],
      [1308787200000.0, 1584.6],
      [1308873600000.0, 1196.62],
      [1308960000000.0, -51.26],
      [1309046400000.0, 991.55],
      [1309132800000.0, 1406.15],
      [1309219200000.0, 1542.91],
      [1309305600000.0, 1494.74],
      [1309392000000.0, 1594.87],
      [1309478400000.0, 1206.89],
      [1309564800000.0, -40.99],
      [1309651200000.0, 1001.82],
      [1309737600000.0, 1416.42],
      [1309824000000.0, 1553.19],
      [1309910400000.0, 1505.01],
      [1309996800000.0, 1605.14],
      [1310083200000.0, 1217.16],
      [1310169600000.0, -30.72],
      [1310256000000.0, 1012.09],
      [1310342400000.0, 1426.69],
      [1310428800000.0, 1563.46],
      [1310515200000.0, 1515.28],
      [1310601600000.0, 1615.41],
      [1310688000000.0, 1227.43],
      [1310774400000.0, -20.45],
      [1310860800000.0, 1022.36],
      [1310947200000.0, 1436.96],
      [1311033600000.0, 1573.73],
      [1311120000000.0, 1525.55],
      [1311206400000.0, 1625.69],
      [1311292800000.0, 1237.7],
      [1311379200000.0, -10.18],
      [1311465600000.0, 1032.63],
      [1311552000000.0, 1447.23],
      [1311638400000.0, 1584.0],
      [1311724800000.0, 1535.82],
      [1311811200000.0, 1635.96],
      [1311897600000.0, 1247.97],
      [1311984000000.0, 0.09],
      [1312070400000.0, 1042.9],
      [1312156800000.0, 1457.5],
      [1312243200000.0, 1594.27],
      [1312329600000.0, 1546.09],
      [1312416000000.0, 1646.23],
      [1312502400000.0, 1258.24],
      [1312588800000.0, 10.36],
      [1312675200000.0, 1053.17],
      [1312761600000.0, 1467.78],
      [1312848000000.0, 1604.54],
      [1312934400000.0, 1556.37],
      [1313020800000.0, 1656.51],
      [1313107200000.0, 1268.52],
      [1313193600000.0, 20.65],
      [1313280000000.0, 1063.47],
      [1313366400000.0, 1478.09],
      [1313452800000.0, 1614.87],
      [1313539200000.0, 1566.7],
      [1313625600000.0, 1666.86],
      [1313712000000.0, 1278.9],
      [1313798400000.0, 31.04],
      [1313884800000.0, 1073.87],
      [1313971200000.0, 1488.5],
      [1314057600000.0, 1625.28],
      [1314144000000.0, 1577.13],
      [1314230400000.0, 1677.29],
      [1314316800000.0, 1289.33],
      [1314403200000.0, 41.47],
      [1314489600000.0, 1084.3],
      [1314576000000.0, 1498.93],
      [1314662400000.0, 1635.72],
      [1314748800000.0, 1587.56],
      [1314835200000.0, 1687.72],
      [1314921600000.0, 1299.76],
      [1315008000000.0, 51.9],
      [1315094400000.0, 1094.74],
      [1315180800000.0, 1509.36],
      [1315267200000.0, 1646.15],
      [1315353600000.0, 1598.0],
      [1315440000000.0, 1698.16],
      [1315526400000.0, 1310.19],
      [1315612800000.0, 62.34],
      [1315699200000.0, 1105.17],
      [1315785600000.0, 1519.8],
      [1315872000000.0, 1656.59],
      [1315958400000.0, 1608.43],
    ],
  },
];

function findAnomalyZones(intervals, values) {
  let validColor = "#25cc7b",
    anomalyColor = "#ff5f5f";
  let zones = Array();
  let prev = null;
  let anomalyType = null; // 1 for above Confidence interval. -1 for below
  for (let i = 0; i < values.length; i++) {
    let interval = intervals[i],
      value = values[i];
    let zone = {
      value: value[0],
    };

    // point is an anomaly
    if (value[1] < interval[1]) {
      anomalyType = -1;
      zone.color = anomalyColor;
    } else if (value[1] > interval[2]) {
      anomalyType = 1;
      zone.color = anomalyColor;
    } else {
      zone.color = validColor;
    }

    // Push prev zone if colors should be different
    // Update prev zone
    if (prev != null && prev.color != zone.color) {
      const interIdx = anomalyType == 1 ? 2 : 1;
      let { m: m1, b: b1 } = findSlopeAndYIntercept(
        [intervals[i - 1][0], intervals[i - 1][interIdx]],
        [interval[0], [interval[interIdx]]]
      );
      let { m: m2, b: b2 } = findSlopeAndYIntercept(values[i - 1], value);
      let { x, y } = findIntersection(m1, b1, m2, b2);

      prev.value = x;
      zones.push(prev);
    }
    prev = zone;
  }

  // Add last zone
  if (zones.length > 0) {
    let lastTimestamp = values[values.length - 1][0];
    zones.push({
      // Some timestamp far beyond the largest timestamp, so that the end of the graph is the right color
      value: lastTimestamp * 2,
      color: prev.color,
    });
  }
  return zones;
}

// Find slope and y-intercept of line between two points
function findSlopeAndYIntercept(p1, p2) {
  const m = (p2[1] - p1[1]) / (p2[0] - p1[0]);
  const b = p1[1] - m * p1[0];
  return {
    m,
    b,
  };
}

// Find the intersection of 2 lines using the slope and y-intercept of each line.
function findIntersection(m1, b1, m2, b2) {
  let x = (b2 - b1) / (m1 - m2);
  let y = m1 * x + b1;
  return {
    x,
    y,
  };
}

// For each graph, plot using Highcharts
graphs.forEach((graphData, i) => {
  let zones = findAnomalyZones(graphData.intervals, graphData.values);

  // Use the container's id instead of i.toString() to map the graph to correct container
  Highcharts.chart(i.toString(), {
    chart: {
      zoomType: "x,y",
      selectionMarkerFill: "rgba(37, 204, 123, 0.25)",
    },
    title: {
      text: graphData.title,
    },
    xAxis: {
      type: "datetime",
      title: {
        text: graphData.x_axis_label,
      },
    },
    yAxis: {
      title: {
        text: graphData.y_axis_label,
      },
    },
    tooltip: {
      crosshairs: true,
      shared: true,
      valueSuffix: null,
    },
    legend: {
      enabled: true,
      borderWidth: 1,
      padding: 20,
      title: {
        text: 'Legend<br/><span style="font-size: 9px; color: #666; font-weight: normal">(Click to hide)',
        style: {
          fontStyle: "italic",
        },
      },
    },
    series: [
      {
        name: "Confidence Interval",
        id: "Confidence Interval",
        data: graphData.intervals,
        type: "arearange",
        lineWidth: 0,
        linkedTo: ":previous",
        color: "#29A374",
        fillOpacity: 0.2,
        zIndex: 0,
        marker: {
          fillColor: "grey",
          enabled: false,
          symbol: "diamond",
        },
      },
      {
        name: "Value",
        id: "value",
        zoneAxis: "x",
        zones: zones,
        data: graphData.values,
        zIndex: 2,
        color: "#25cc7b",
        marker: {
          fillColor: "white",
          lineWidth: 1,
          lineColor: "grey",
          symbol: "circle",
        },
      },
      {
        name: "Predicted Value",
        id: "predicted_value",
        visible: false,
        type: "line",
        data: graphData.predicted_values,
        zIndex: 1,
        color: "#02964e",
        dashStyle: "Dash",
        opacity: 0.5,
        marker: {
          fillColor: "gray",
          lineWidth: 1,
          radius: 2,
          lineColor: "white",
          enabled: false,
          symbol: "circle",
        },
      },
    ],
  });
});
